package cn.buddha.jec.util;

import cn.buddha.jec.exception.enums.TongExceptionEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName TongDateUtils
 * @description 时间工具类
 * @Author 友野浩二
 * @Version 1.0
 **/
@Slf4j
public class TongDateUtils {

    // 日期格式,此处定义为public的目的为了其他类在调用该类的方法时，作为入参
    public static final String PATTERN_ISO_DATE = "yyyy-MM-dd";
    public static final String PATTERN_ISO_TIME = "HH:mm:ss";
    public static final String PATTERN_ISO_DATETIME = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_ISO_FULL = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String PATTERN_SIMPLE_DATE = "yyyyMMdd";
    public static final String PATTERN_SIMPLE_TIME = "HHmmss";
    public static final String PATTERN_SIMPLE_DATETIME = "yyyyMMddHHmmss";
    public static final String PATTERN_SIMPLE_FULL = "yyyyMMddHHmmssSSS";

    public static final String DEFAULT_ISO_DATE = PATTERN_ISO_DATE;

    private static ThreadLocal<Map<String, DateFormat>> localDateFormat = ThreadLocal.withInitial(() ->
            // 当lambda表达式只包含一条语句时，可以省略大括号、return和语句结尾的分号
            new HashMap<String, DateFormat>() {
                private static final long serialVersionUID = 6794453143364126583L;

                {
                    put(PATTERN_ISO_DATE, new SimpleDateFormat(PATTERN_ISO_DATE));
                    put(PATTERN_ISO_TIME, new SimpleDateFormat(PATTERN_ISO_TIME));
                    put(PATTERN_ISO_DATETIME, new SimpleDateFormat(PATTERN_ISO_DATETIME));
                    put(PATTERN_ISO_FULL, new SimpleDateFormat(PATTERN_ISO_FULL));
                    put(PATTERN_SIMPLE_DATE, new SimpleDateFormat(PATTERN_SIMPLE_DATE));
                    put(PATTERN_SIMPLE_TIME, new SimpleDateFormat(PATTERN_SIMPLE_TIME));
                    put(PATTERN_SIMPLE_DATETIME, new SimpleDateFormat(PATTERN_SIMPLE_DATETIME));
                    put(PATTERN_SIMPLE_FULL, new SimpleDateFormat(PATTERN_SIMPLE_FULL));
                }
            }
    );

    /**
     * @return java.lang.String
     * @Author 友野浩二
     * @Description // 获取当前时间戳(yyyy-MM-dd HH:mm:ss.SSS)
     * @Param []
     **/
    public static String createNowTimestamp() {
        Date date = new Date();
        DateFormat dateFormat = new SimpleDateFormat(PATTERN_ISO_FULL);
        return dateFormat.format(date);
    }

    /**
     * @return java.lang.String
     * @Author 友野浩二
     * @Description // 获取当前日期
     * @Date 2020/4/5 1:29
     * @Param []
     */
    public static String getDate() {
        Date date = new Date();
        DateFormat dateFormat = new SimpleDateFormat(PATTERN_SIMPLE_DATE);
        return dateFormat.format(date);
    }

    /**
     * @return java.lang.String
     * @Author 友野浩二
     * @Description // 获取当前日期
     * @Date 2020/4/5 14:50
     * @Param []
     */
    public static String getToday() {
        LocalDate localDate = LocalDate.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(PATTERN_SIMPLE_DATE);
        return localDate.format(dateTimeFormatter);
    }

    /*
     * @Author 友野浩二
     * @Description // 将字符串日期根据指定格式转换为date类型
     * @Param [strDate 字符串日期, pattern 格式(可以不传),默认为 yyyy-MM-dd]
     * @return java.util.Date
     *
     * @deprecated 已过时,推荐使用方法 convertStr2Date(String strDate, final String pattern) 来代替
     **/
    @Deprecated
    public static Date transferStr2Date(String strDate, final String pattern) {
        if (StringUtils.isEmpty(strDate)) {// 判断是否为空,如果为空,则返回null
            return null;
        }

        Date date = null;
        DateFormat dateFormat = new SimpleDateFormat(getPattern(pattern));
        try {
            date = dateFormat.parse(strDate);
        } catch (ParseException e) {
            log.error(TongExceptionEnum.DATE_PARSE_FAILED.getCode(), e);
        }

        return date;
    }

    /*
     * @Author 友野浩二
     * @Description // 将字符串日期根据指定格式转换为date类型
     * @Param [strDate 字符串日期, pattern 格式(可以不传),默认为 yyyy-MM-dd]
     * @return java.util.Date
     **/
    public static Date convertStr2Date(String strDate, final String pattern) {
        if (StringUtils.isEmpty(strDate)) {
            return null;
        }

        Date date = null;
        try {
            date = getDateFormat(getPattern(pattern)).parse(strDate);
        } catch (ParseException e) {
            log.error(TongExceptionEnum.DATE_PARSE_FAILED.getCode(), e);
        }

        return date;
    }

    /**
     * @return java.lang.String
     * @Author 友野浩二
     * @Description // 将Date日期根据指定格式转换为字符串日期
     * @Param [date, pattern 格式(可以不传),默认为 yyyy-MM-dd]
     **/
    public static String convertDate2Str(Date date, final String pattern) {
        if (date == null) {
            return null;
        }

        return getDateFormat(getPattern(pattern)).format(date);
    }

    /* ============================== 【private 方法】 ============================== */

    private static String getPattern(final String pattern) {
        // 如果日期格式为空,则使用默认格式"yyyy-MM-dd"
        return StringUtils.isEmpty(pattern) ? DEFAULT_ISO_DATE : pattern;
    }

    /**
     * @return java.text.DateFormat
     * @Author 友野浩二
     * @Description // 获取DateFormat
     * @Param [pattern]
     **/
    private static DateFormat getDateFormat(String pattern) {
        if (localDateFormat.get().containsKey(pattern)) {
            return localDateFormat.get().get(pattern);
        }

        DateFormat dateFormat = new SimpleDateFormat(pattern);
        localDateFormat.get().put(pattern, dateFormat);
        return dateFormat;
    }

}
